(function ($) {
    $.fn.extend({
        dateInput: function (setting) {
            var opt = { inputFormat:'[dd]/[mm]/[yy]', onInit: null, onFinish: null };	//outputFormat:'[dth] [month], [yy]/[y]/[mon]/[dd]/[d]/[mm]/[m]'

            setting = setting || {};
            $.extend(opt, setting);

            var monName = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
            var monthName = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');

            var today = new Date();
            var today_y = parseInt(today.getFullYear());
            var today_m = parseInt(today.getMonth()) + 1;
            var today_d = parseInt(today.getDate());
            var today_id = 'd_' + today_y + '_' + (today_m) + '_' + today_d;
            //	var monSwitch = switchInit();

            $(this).each(function () {
                var input = $(this);
                var inputId = this.id;
                var inputVal = input.val();
                var inputPlaceholder = input.attr('placeholder') ? '<i class="placeholder">' + input.attr('placeholder') + '</i>' : '';

                input.wrap('<span class="dateInput"></span>').before('<div id="dateInput' + inputId + '"></div>');

                var dateArea = $('#dateInput' + inputId);
                var dateFormatInput = input;

                if( opt.onInit ) opt.onInit(input, inputVal);
                if(opt.outputFormat){
                    var output = input.data('y-m-d') ? dateFormatShow(input.data('y-m-d'), opt.outputFormat) : inputPlaceholder;

                    input.hide().before('<span id=dateFor' + inputId + ' class="dateFormat">' + output + '</span>\
						<a href="javascript:void(0);" title="clear" class="dateClear"></a>');

                    dateFormatInput = $('#dateFor' + inputId);
                    // clear input value
                    dateArea.parent().hover(function () {
                        dateFormatInput.next('a').show();
                    }, function () {
                        dateFormatInput.next('a').hide();
                    });
                    dateFormatInput.next('a').click(function () {
                        dateFormatInput.html(inputPlaceholder);
                        input.val('');
                        hideCalender();
                    });
                }

                dateFormatInput.click(function () {
                    hideCalender();
                    calenderInit(dateArea, input, this);
                });

            });

            $('body').on('click', function (e) {
                var eventIn = $(e.target).parentsUntil('.dateInput');
                if (eventIn.eq(eventIn.length - 1).is('html')) {
                    hideCalender();
                }
            });

            function calenderInit(dateArea, input, target){
                dateArea.html('<p id="dateInputSwitch"></p><ul id="dateInputCalendar" class="calendar"></ul>');
                if (input.data('y-m-d') && input.data('y-m-d').split('-').length == 3) {
                    var inputDate = input.data('y-m-d').split('-');
                    var inputDateYear = Number(inputDate[0]) ? Number(inputDate[0]) : today_y;
                    var inputDateMonth = Number(inputDate[1]) ? Number(inputDate[1]) : today_m;
                    var inputDateDay = Number(inputDate[2]) ? Number(inputDate[2]) : today_d;
                    dateInit(inputDateYear, inputDateMonth, inputDateDay, input, target);
                } else {
                    dateInit(today_y, today_m, null, input, target);
                }
            }

            function dateInit(y, m, d, input, target) {	// 可优化与 switchMon() 整合
                $('#dateInputSwitch').html(switchInit());

                $('#dateInputCalendar').html(SetCalendar(y, m));
                $('#dateInputCalendar').parent().show().parent().addClass('dateActive');

                $('#dateInput_mon').val(m);
                $('#dateInput_year').val(y);

                if (d) {
                    $('#d_' + y + '_' + m + '_' + d).addClass('current');
                }
                $('#' + today_id).addClass('today');

                $('#dateInputCalendar').delegate('a', 'click', function () {
                    var thedate = this.id.replace('d_', '').split('_');
                    if( target.tagName.toLowerCase() != 'input' ) {
                        $(target).html(dateFormatShow(thedate, opt.outputFormat));
                    }
                    input.val(normalFormat(thedate, opt.inputFormat));
                    input.data('y-m-d', thedate.join('-'));
                    if (opt.onFinish) opt.onFinish(input);
                    hideCalender();
                });

                $('#dateInputSwitch').delegate('select', 'click', function () {
                    switchMon();
                });

            }

            function normalFormat( thedate, format ){
                var yy = Number(thedate[0]), m = Number(thedate[1]), d = Number(thedate[2]);
                var mm = m > 9 ? m : '0' + m;
                var dd = d > 9 ? d : '0' + d;
                var y = yy % 100;
                var value = format.replace('[dd]', dd).replace('[d]', d).replace('[mm]', mm).replace('[yy]', yy).replace('[y]', y);
                return value;
            }

            function dateFormatShow(thedate, format) {
                var format = normalFormat(thedate, format);
                var yy = Number(thedate[0]), m = Number(thedate[1]), d = Number(thedate[2]);

                if ( format.indexOf('[dth]') != -1 ) {
                    var Dayth = '';
                    switch (d) {
                        case 1: Dayth = '1<sup>st</sup>'; break;
                        case 2: Dayth = '2<sup>nd</sup>'; break;
                        case 3: Dayth = '3<sup>rd</sup>'; break;
                        default: Dayth = d + '<sup>th</sup>';
                    }
                    debugger;
                    format = format.replace('[dth]', Dayth);
                }

                if( format.indexOf('[month]') != -1 ){
                    var MonName = monthName[(m - 1)];
                    format = format.replace('[month]', MonName);
                } else if( format.indexOf('[mon]') != -1 ){
                    var MonName = monName[(m - 1)];
                    format = format.replace('[mon]', MonName);
                }
                return format;
            }

            function switchInit() {
                var year_list = '';
                var mon_list = '';

                for (var i = 0; i <= 5; i++) {
                    var option = i == 0 ? '<option value="' + (today_y + i) + '" selected="selected">' + (today_y + i) + '</option>' : '<option value="' + (today_y + i) + '">' + (today_y + i) + '</option>';
                    year_list += option;
                }
                for (var i = 0; i < 12; i++) {
                    var option = i == (today_m - 1) ? '<option selected="selected" value="' + (i + 1) + '">' + monName[i] + '</option>' : '<option value="' + (i + 1) + '">' + monName[i] + '</option>';
                    mon_list += option;
                }
                var switch_m = '<select id="dateInput_mon">' + mon_list + '</select><select id="dateInput_year">' + year_list + '</select>';

                return switch_m;
            }

            function switchMon() {
                var y = $('#dateInput_year').val();
                var m = $('#dateInput_mon').val();
                var dateList = SetCalendar(y, m);
                $('#dateInputCalendar').html(dateList);
                $('#' + today_id).addClass('today');
            }

            function hideCalender() {
                var calenderArea = $('#dateInputCalendar').parent();
                //	var input = $('#dateInput').parent().next();
                calenderArea.parent().removeClass('dateActive');
                calenderArea.hide().html('');
                calenderArea.next('input').focus();
                if(opt.outputFormat){
                    calenderArea.prev('a').hide();
                }
            }
            // 给定年月获取当月天数
            function getMonthDay(y, m) {
                var mday = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
                if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)//判断是否是闰月
                    mday[1] = 29;
                return mday[m - 1];
            }
            // 获取星期数
            function weekNumber(y, m, d) {
                var wk;
                if (m <= 12 && m >= 1) {
                    for (var i = 1; i < m; ++i) { d += getMonthDay(y, i); }
                }
                wk = (y - 1 + (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400 + d) % 7; // 根据日期计算星期的公式 - 0对应星期天，1对应星期一
                return parseInt(wk);
            }
            function SetCalendar(year, month) {
                var daynumber = getMonthDay(year, month); //当月天数
                var firstnumber = weekNumber(year, month, 1); //当月第一天星期
                var lastnumber = weekNumber(year, month, daynumber); //当月最后一天星期
                var weeknumber = (daynumber - (7 - firstnumber) - (lastnumber + 1)) / 7; //除去第一个星期和最后一个星期的周数
                var day = 1;
                var name;
                var calendar = '';

                calendar += '<li class="week_name"><span>S</span><span>M</span><span>T</span><span>W</span><span>T</span><span>F</span><span>S</span></li>';

                calendar += '<li class="week_first">';
                var i = 0;
                for (i = 0; i < firstnumber; i++) {//第一个星期
                    calendar += '<span class="dayPrevM d_wk_' + i + '"></span>';
                }
                for (i = firstnumber; i < 7; i++) {
                    name = 'd_' + year + '_' + month + '_' + day;
                    calendar += '<a href="javascript:void(0);" id="' + name + '" class="d_wk_' + i + '">' + day + '</a>';
                    day++;
                }
                calendar += '</li>';
                var number = 0; //星期数，末尾添加空行用，统一样式。
                for (i = 0; i < weeknumber; i++) {//其他星期
                    calendar += '<li class="week_' + (i + 2) + '">';
                    for (var k = daynumber - (7 - firstnumber) - (weeknumber - 1) * 7; k < daynumber - (7 - firstnumber) - (weeknumber - 1) * 7 + 7; k++) {
                        name = 'd_' + year + '_' + month + '_' + day;
                        calendar += '<a href="javascript:void(0);" id="' + name + '" class="d_wk_' + ((day + firstnumber - 1) % 7) + '">' + day + '</a>';
                        day++;
                    }
                    calendar += '</li>';
                    number++;
                }

                calendar += '<li class="week_last">';
                for (i = 0; i < lastnumber + 1; i++) { //最后一个星期
                    name = 'd_' + year + '_' + month + '_' + day;
                    calendar += '<a href="javascript:void(0);" id=\'' + name + '\' class="d_wk_' + i + '">' + day + '</a>';
                    day++;
                }
                for (i = lastnumber + 1; i < 7; i++) { calendar += '<span class="dayNextM d_wk_' + i + '"></span>'; }
                calendar += '</li>';

                if (number == 3) {
                    calendar += '<li>';
                    for (i = 0; i < 7; i++) { calendar += '<span class="dayNextM d_wk_' + i + '"></span>'; }
                    calendar += '</li>';
                }
                return calendar;
            }
        }
    })
})(jQuery);